package br.leiam.eolica.sistema;

import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.UIManager;

import sun.misc.BASE64Decoder;
import br.leiam.eolica.excecoes.EolicaException;
import br.leiam.eolica.funcoes.ProducaoEnergia;
import br.leiam.eolica.graficos.CurvaAerogerador;
import br.leiam.eolica.graficos.Dados;
import br.leiam.eolica.graficos.Frequencia;
import br.leiam.eolica.graficos.Tabela;
import br.leiam.eolica.graficos.RosaDosVentosFrequencia;
import br.leiam.eolica.graficos.RosaDosVentosVelocidades;
import br.leiam.eolica.graficos.Velocidade;
import br.leiam.eolica.graficos.Weibull;
import br.leiam.eolica.util.Logger;

public class GerenciadorDeGraficos {

	private static final int LARGURA_DEFAULT = 300;
	private static final int ALTURA_DEFAULT = 190;
	public static final int ALTURA_30M = 30;
	public static final int ALTURA_50M = 50;
	public static final int ALTURA_100M = 100;

	public static int TIPO_VELOCIDADE = 1;
	public static int TIPO_RV_E_WEIBULL = 2;

	private static GerenciadorDeGraficos singleton;

	public static GerenciadorDeGraficos getInstance() {
		if (singleton == null)
			singleton = new GerenciadorDeGraficos();
		return singleton;
	}

	private GerenciadorDeGraficos() {
	}

	public static byte[] decode(String figura) throws EolicaException {
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] figurasDecodificadas;
		try {
			figurasDecodificadas = decoder.decodeBuffer(figura);
		} catch (IOException e) {
			throw new EolicaException(e.getMessage());
		}
		return figurasDecodificadas;

	}

	public String[] gerarGraficoRosaDosVentosEWeibull(String estacao,
			int altura, String dataInicial, String dataFinal)
			throws EolicaException {
		return gerarGraficoRosaDosVentosEWeibull(estacao, altura, dataInicial,
				dataFinal, ALTURA_DEFAULT, LARGURA_DEFAULT);

	}

	public String[] gerarGraficoRosaDosVentosEWeibull(String estacao,
			int altura, String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		// VALORES PARA BROWSER
		// imageWidth = 350;
		// imageHeight = 350;
		testarParametros(altura, imageHeight, imageWidth);
		String[] figuras = new String[3];
		RosaDosVentosFrequencia RVFrequencia = new RosaDosVentosFrequencia(
				estacao, altura ,dataInicial, dataFinal, imageWidth, imageHeight);
		RosaDosVentosVelocidades RVVelocidades = new RosaDosVentosVelocidades(
				estacao, dataInicial, dataFinal, altura, imageWidth,
				imageHeight);
		Weibull weibull = new Weibull(estacao,  dataInicial, dataFinal, altura,//FIXME
				imageWidth, imageHeight);

		figuras[0] = RVFrequencia.getBase64String();
		figuras[1] = RVVelocidades.getBase64String();
		figuras[2] = weibull.getBase64String();
		return figuras;
	}

	public String[] gerarGraficoRosaDosVentosFrequencia(String estacao,
			int altura, String dataInicial, String dataFinal)
			throws EolicaException {
		return gerarGraficoRosaDosVentosFrequencia(estacao, altura,
				dataInicial, dataFinal, ALTURA_DEFAULT, LARGURA_DEFAULT);

	}

	public String[] gerarGraficoRosaDosVentosFrequencia(String estacao,
			int altura, String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		// VALORES PARA BROWSER
		// imageWidth = 350;
		// imageHeight = 350;
		testarParametros(altura, imageHeight, imageWidth);
		String[] figuras = new String[1];
		RosaDosVentosFrequencia RVFrequencia = new RosaDosVentosFrequencia(
				estacao,altura,dataInicial, dataFinal, imageWidth, imageHeight);

		figuras[0] = RVFrequencia.getBase64String();
		return figuras;
	}

	public String[] gerarGraficoRosaDosVentosVelocidades(String estacao,
			int altura, String dataInicial, String dataFinal)
			throws EolicaException {
		return gerarGraficoRosaDosVentosVelocidades(estacao, altura,
				dataInicial, dataFinal, ALTURA_DEFAULT, LARGURA_DEFAULT);

	}

	public String[] gerarGraficoRosaDosVentosVelocidades(String estacao,
			int altura, String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		// VALORES PARA BROWSER
		// imageWidth = 350;
		// imageHeight = 350;
		testarParametros(altura, imageHeight, imageWidth);
		String[] figuras = new String[1];
		RosaDosVentosVelocidades RVVelocidades = new RosaDosVentosVelocidades(
				estacao, dataInicial, dataFinal, altura, imageWidth,
				imageHeight);

		figuras[0] = RVVelocidades.getBase64String();

		return figuras;
	}

	public String[] gerarGraficoVelocidade(String estacao, int altura,
			String dataInicial, String dataFinal) throws EolicaException {
		return gerarGraficoVelocidade(estacao, altura, dataInicial, dataFinal,
				ALTURA_DEFAULT, LARGURA_DEFAULT);

	}

	public String[] gerarGraficoVelocidade(String estacao, int altura,
			String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		// VALORES PARA BROWSER
		// imageWidth = 600;
		// imageHeight = 350;
		testarParametros(altura, imageHeight, imageWidth);
		String[] figuras = new String[1];
		Velocidade velocidade = new Velocidade(estacao, dataInicial, dataFinal,
				altura, imageWidth, imageHeight);
		figuras[0] = velocidade.getBase64String();
		return figuras;
	}

	public String[] gerarGraficoFreqAeroProdEnergia(String estacao, int altura, String turbina,
			String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		String[] figuras = new String[3];
		// Gera o grafico de Frequencia
		Frequencia gFrequencia = new Frequencia(estacao, altura, dataInicial,
				dataFinal, imageWidth, imageHeight);
		// Gera Grafico curvaAerogerador
		CurvaAerogerador curvaAerogerador = new CurvaAerogerador(turbina,
				imageWidth, imageHeight);
		ProducaoEnergia calculoEAG = new ProducaoEnergia();
		calculoEAG.setCurvaPotencia(curvaAerogerador.getPotencia());
		calculoEAG.setFreqRelativa(gFrequencia.getFrequenciaRelativa());
		calculoEAG.calcularEAG();
		
		Dados dados = new Dados(gFrequencia.getVelocidadeVentoMedio(),
				gFrequencia.getFrequenciaRelativa(),
				curvaAerogerador.getPotencia(), calculoEAG.getFvpv(),
				calculoEAG.getSumfvpv(), calculoEAG.getEAG());
		
		/*TabelaProdEnergia modeloTabela = new TabelaProdEnergia(
				calculoEAG.getFvpv(), gFrequencia.getVelocidadeVentoMedio(),
				gFrequencia.getFrequenciaRelativa(),
				curvaAerogerador.getPotencia());
		ResultadoProdEnergia prodEnergia = new ResultadoProdEnergia(
				modeloTabela);// Gera Grafico Producao de Energia
		prodEnergia.setRodape((calculoEAG.getSumfvpv()));
		prodEnergia.setLabelEAG(calculoEAG.getEAG() / 1000);
		TesteFrame tf = new TesteFrame();
		tf.add(prodEnergia);
		tf.setBounds(0, 0, 500, 495);*/
		figuras[0] = gFrequencia.getBase64String();
		figuras[1] = curvaAerogerador.getBase64String();
		//figuras[2] = prodEnergia.getBase64String();
		figuras[2] = getProdEnergia(dados,imageHeight, imageWidth);
		return figuras;
	}

	public String[] gerarGraficoFreqAeroProdEnergia(String estacao, int altura, String turbina,
			String dataInicial, String dataFinal) throws EolicaException {
		return gerarGraficoFreqAeroProdEnergia(estacao, altura, turbina, dataInicial,
				dataFinal, 450, 450);// valores para browser
	}

	public String[] gerarGraficoFrequenciaDeDistribuicao(String estacao,
			int altura, String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		String[] figuras = new String[1];
		// Gera o grafico de Frequencia
		Frequencia gFrequencia = new Frequencia(estacao, altura, dataInicial,
				dataFinal, imageWidth, imageHeight);
		figuras[0] = gFrequencia.getBase64String();
		return figuras;
	}

	public String[] gerarGraficoFrequenciaDeDistribuicao(String estacao,
			int altura, String dataInicial, String dataFinal)
			throws EolicaException {
		return gerarGraficoFrequenciaDeDistribuicao(estacao, altura,
				dataInicial, dataFinal, 450, 450);// valores para browser
	}

	public String[] gerarGraficoCurvaPotenciaAerogerador(String estacao,
			int altura, String turbina, String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		String[] figuras = new String[1];
		// Gera Grafico curvaAerogerador
		CurvaAerogerador curvaAerogerador = new CurvaAerogerador(turbina,
				imageWidth, imageHeight);
		figuras[0] = curvaAerogerador.getBase64String();
		return figuras;
	}

	public String[] gerarGraficoCurvaPotenciaAerogerador(String estacao,
			int altura, String turbina, String dataInicial, String dataFinal)
			throws EolicaException {
		return gerarGraficoCurvaPotenciaAerogerador(estacao, altura, turbina,
				dataInicial, dataFinal, 450, 450);// valores para browser
	}

	public String[] gerarTabela(String estacao, int altura, String turbina ,String dataInicial,
			String dataFinal, int imageHeight, int imageWidth)
			throws EolicaException {
		String[] figuras = new String[3];
		// Gera o grafico de Frequencia
		Frequencia gFrequencia = new Frequencia(estacao, altura, dataInicial,
				dataFinal, imageWidth, imageHeight);
		// Gera Grafico curvaAerogerador
		CurvaAerogerador curvaAerogerador = new CurvaAerogerador(turbina,
				imageWidth, imageHeight);
		ProducaoEnergia calculoEAG = new ProducaoEnergia();
		calculoEAG.setCurvaPotencia(curvaAerogerador.getPotencia());
		calculoEAG.setFreqRelativa(gFrequencia.getFrequenciaRelativa());
		calculoEAG.calcularEAG();
		
		Dados dados = new Dados(gFrequencia.getVelocidadeVentoMedio(),
				gFrequencia.getFrequenciaRelativa(),
				curvaAerogerador.getPotencia(), calculoEAG.getFvpv(),
				calculoEAG.getSumfvpv(), calculoEAG.getEAG());
				
		
		figuras[0] = getProdEnergia(dados, imageHeight,imageWidth);
		return figuras;
		
		/*TabelaProdEnergia modeloTabela = new TabelaProdEnergia(
				calculoEAG.getFvpv(), gFrequencia.getVelocidadeVentoMedio(),
				gFrequencia.getFrequenciaRelativa(),
				curvaAerogerador.getPotencia());
		ResultadoProdEnergia prodEnergia = new ResultadoProdEnergia(
				modeloTabela);// Gera Grafico Producao de Energia
		prodEnergia.setRodape((calculoEAG.getSumfvpv()));
		prodEnergia.setLabelEAG(calculoEAG.getEAG() / 1000);
		TesteFrame tf = new TesteFrame();
		tf.add(prodEnergia);
		tf.setBounds(0, 0, 500, 495);
		figuras[0] = prodEnergia.getBase64String();
		return figuras;*/
	}
	//CODIGO ALTAMENTE ACOPLADO
	private static String getProdEnergia(Dados dados,int imageHeight, int imageWidth ) {
		String prodEnergia = "";
		try {
			UIManager.setLookAndFeel(UIManager
					.getCrossPlatformLookAndFeelClassName());
			JFrame frame = new JFrame("Frame");

			Tabela painel = new Tabela(dados,imageHeight,imageWidth);

			frame.getContentPane().add(painel);
			frame.pack();
			prodEnergia = painel.getBase64String();
			frame.setVisible(false);
			frame.dispose();
			frame = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return prodEnergia;
	}
	
	

	public String[] gerarTabela(String estacao, int altura, String turbina, String dataInicial,
			String dataFinal) throws EolicaException {
		return gerarTabela(estacao, altura, turbina ,dataInicial, dataFinal, 450, 450);// valores
																				// para
																				// browser
	}

	public String[] gerarWeibull(String estacao, int altura, 
			String dataInicial, String dataFinal, int imageHeight,
			int imageWidth) throws EolicaException {
		String[] figuras = new String[1];
		Weibull weibull = new Weibull(estacao,  dataInicial, dataFinal, altura,
				imageWidth, imageHeight);
		figuras[0] = weibull.getBase64String();
		return figuras;
	}

	public String[] gerarWeibull(String estacao, int altura,
			String dataInicial, String dataFinal) throws EolicaException {
		// Tamanhos encontrado no EolicaServer.java
		return gerarWeibull(estacao, altura,  dataInicial, dataFinal, 380, 480);
	}

	/*public String[] gerarAerogerador(String aerogerador) {
		String[] graficos = new String[2];
		String station = "";
		if (aerogerador.equals("1"))
			station = "500kw";
		if (aerogerador.equals("2"))
			station = "1.5mw";
		if (aerogerador.equals("3"))
			station = "2.0mw";
		if (aerogerador.equals("4"))
			station = "2.1mw";
		CurvaAerogerador curvaAerogerador = new CurvaAerogerador(station, 400,
				350);
		TabelaCurvaAerogerador tab = new TabelaCurvaAerogerador(
				curvaAerogerador.getVelocidadeVentoMedio(),
				curvaAerogerador.getPotencia());
		PanelTabelaCurvaAerogerador pt = new PanelTabelaCurvaAerogerador(tab);
		TesteFrame tf = new TesteFrame();
		tf.add(pt);
		tf.setSize(300, 394);
		graficos[0] = curvaAerogerador.getBase64String();
		graficos[1] = pt.getBase64String();
		return graficos;
	}*/

	public static String getAltura(int altura) {// FIXME VAI PRECISAR MESMO
												// DESTE METODO??
		if (altura == ALTURA_30M) {
			return "30m";
		} else if (altura == ALTURA_50M) {
			return "50m";
		} else
			return "100m";
	}

	

	private void testarParametros(int altura, int imageHeight, int imageWidth)
			throws EolicaException {
		EolicaException e;
		if (imageHeight < 1 || imageWidth < 1) {
			e = new EolicaException("Tamanho da imagem invalido");
			Logger.getInstance().logExcecao(e.getMessage());
			throw e;
		}
		/*
		 * if (altura != 13 && altura != 70 && altura != 100 ){ e = new
		 * EolicaException("Altura invalida");
		 * Logger.getInstance().logExcecao(e.getMessage()); throw e; }
		 */
	}
}
